﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Reticle.Core;
using BNSharp;
using System.Windows.Forms;
using System.Web;
using System.Threading;

namespace WebBotPlugin
{
    public class Plugin : IPlugin
    {
        public IHost Bot;
        public ToolStripMenuItem myMenu = new ToolStripMenuItem();
        public string Enable { get; private set; }
        public string UserID { get; set; }
        public string Password { get; set; }
        public bool ShowWhispers { get; set; }
        WebBot WebBot { get; set; }
        public const string WebURL = "http://api.bnetweb.org/webbot.php?";

        public string Channel { get; set; }

        // hold the users currently in channel (UserShown)
        public string Users { get; set; }

        // hold the count of users in the channel (UserShown)
        public int UserCount { get; set; }

        #region IPlugin Members

        public string Author
        {
            get { return "Scope"; }
        }

        public string Name
        {
            get { return "BnetWeb WebBot"; }
        }

        public string Description
        {
            get { return "Stream your channel in real time to the web"; }
        }

        public string Filename
        {
            get { return "WebBot.dll"; }
        }

        public string URL
        {
            get { return "http://webbot.bnetweb.org"; }
        }

        public void Initialize(IHost host)
        {
            Bot = host;
            ReloadSettings();

            WebBot = new WebBot();

            // Create the plugin menu (and submenus if any)
            EventHandler e = new EventHandler(myMenus_Click);
            myMenu.Text = "WebBot";
            myMenu.DropDownItems.Add(PluginFunctions.NewToolMenu("ViewWebChannel", "View WebChannel", e));
            myMenu.DropDownItems.Add(new ToolStripSeparator());
            myMenu.DropDownItems.Add(PluginFunctions.NewToolMenu("Enable", "Enable", e, isEnabled()));
            myMenu.DropDownItems.Add(PluginFunctions.NewToolMenu("Config", "Config", e));
            Bot.SetPluginMenu(myMenu);

            Thread prep = new Thread(new ThreadStart(PrepWebBot));
            prep.Start();
        }

        public void Unload()
        {
            string clearall = String.Format("{0}u={1}&p={2}&f={3}&c={4}", WebURL, UserID, Password, 11, "clr+all");
            WebBot.Send(clearall);

            Bot.UnloadPlugin();
        }

        // handles the click event of each menu item
        void myMenus_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem m = (ToolStripMenuItem)sender;
            switch (m.Name)
            {
                case "ViewWebChannel":
                    string url = String.Format("http://webbot.bnetweb.org/{0}.html", UserID);
                    System.Diagnostics.Process.Start(url);
                    break;
                case "Enable":
                    if (m.Checked)
                    {
                        // save setting for enabled
                        Bot.SavePluginSetting("enable", "1");

                        Bot.AddChat("#00FF00", "[WebBot] Enabled.");
                    }
                    else
                    {
                        // save setting for disabled
                        Bot.SavePluginSetting("enable", "0");

                        Bot.AddChat("#F0493C", "[WebBot] Disabled.");
                    }
                    ReloadSettings();
                    break;
                case "Config":
                    Bot.ShowForm(new WebBotSetup(this));
                    break;
            }
        }

        bool isEnabled()
        {
            if (Enable == "1")
            {
                return true;
            }

            return false;
        }

        public void ReloadSettings()
        {
            // Get the settings for WebBot connection
            Enable = (string)Bot.GetPluginSetting("enable");
            UserID = (string)Bot.GetPluginSetting("userid");
            Password = (string)Bot.GetPluginSetting("password");

            if ((string)Bot.GetPluginSetting("showwhispers") == "1")
            {
                ShowWhispers = true;
            }
            else
            {
                ShowWhispers = false;
            }
        }

        public void SaveSettings()
        {
            Bot.SavePluginSetting("userid", UserID);
            Bot.SavePluginSetting("password", Password);

            if (ShowWhispers)
            {
                Bot.SavePluginSetting("showwhispers", "1");
            }
            else
            {
                Bot.SavePluginSetting("showwhispers", "0");
            }

            Bot.AddChat("#00FF00", "[WebBot] Settings saved.");

            // prep the webbot with new info
            Thread prep = new Thread(new ThreadStart(PrepWebBot));
            prep.Start();
        }

        public void PrepWebBot()
        {
            Thread.Sleep(1000);
            bool valid = false;

            // attempt to create the webbot
            string var1 = WebBot.SendReturnURL(Plugin.WebURL + "u=" + HttpUtility.UrlEncode(UserID) + "&p=" + HttpUtility.UrlEncode(Password) + "&f=99");

            if (var1.ToLower().Contains("ok"))
            {
                Bot.AddChat("#00FF00", "[WebBot] Ready to begin streaming.");
                valid = true;
            }
            else if (var1.ToLower().Contains("invalid password"))
            {
                Bot.AddChat("#F0493C", "[WebBot] Invalid Password.");
            }
            else if (var1.ToLower().Contains("successfully"))
            {
                Bot.AddChat("#00FF00", "[WebBot] " + var1);
                valid = true;
            }
            else
            {
                Bot.AddChat("#F0493C", "[WebBot] An error occurred when communicating with the server. Please report this.");
                valid = false;
            }

            // UserID checks out
            if (valid)
            {
                // lets clear everything from before (if bot isn't connected)
                if (!Bot.IsConnected())
                {
                    string clearall = String.Format("{0}u={1}&p={2}&f={3}&c={4}", WebURL, UserID, Password, 11, "clr+all");
                    WebBot.Send(clearall);
                }

                Bot.AddChat("#00FF00", "[WebBot] http://webbot.bnetweb.org/" + UserID + ".html");
            }

        }

        #region Battle.net Events
        // When the bot establishes a connection to Battle.net
        public void Connected(object sender, EventArgs e)
        {
            if (Enable == "1")
            {
                string version = String.Format("{0}u={1}&p={2}&f={3}&v={4}", WebURL, UserID, Password, 15, HttpUtility.UrlEncode((string)Bot.GetVersion()));
                WebBot.Send(version);

                string server = String.Format("{0}u={1}&p={2}&f={3}&s={4}", WebURL, UserID, Password, 10, HttpUtility.UrlEncode((string)Bot.GetConfigSetting("server")));
                WebBot.Send(server);
            }
        }

        // When the bot is disconnected from Battle.net (for any reason)
        public void Disconnected(object sender, EventArgs e)
        {
            if (Enable == "1")
            {
                string url = String.Format("{0}u={1}&p={2}&f={3}&c={4}", WebURL, UserID, Password, 11, "clr+all");
                WebBot.Send(url);
            }
        }

        // When the bot receives an error from Battle.net (i.e. no friends)
        public void ServerErrorReceived(object sender, ServerChatEventArgs e)
        {
            if (Enable == "1")
            {
                string url = String.Format("{0}u={1}&p={2}&f={3}&d={4}&t={5}",
                        WebURL, UserID, Password, 0, HttpUtility.UrlEncode(WebBot.TimeStamp()), HttpUtility.UrlEncode(e.Text));

                WebBot.Send(url);
            }
        }

        // When the bot receives information (i.e. friends list)
        public void InformationReceived(object sender, ServerChatEventArgs e)
        {
            if (Enable == "1")
            {
                string url = String.Format("{0}u={1}&p={2}&f={3}&d={4}&t={5}",
                        WebURL, UserID, Password, 1, HttpUtility.UrlEncode(WebBot.TimeStamp()), HttpUtility.UrlEncode(e.Text));

                WebBot.Send(url);
            }
        }

        // When the bot enters chat
        public void EnteredChat(object sender, EnteredChatEventArgs e)
        {

        }

        // When the bot joins a channel (everytime it joins a channel)
        public void JoinedChannel(object sender, ServerChatEventArgs e)
        {
            if (Enable == "1")
            {
                Channel = HttpUtility.UrlEncode(e.Text);
                string url = String.Format("{0}u={1}&p={2}&f={3}&d={4}&ch={5}",
                        WebURL, UserID, Password, 2, HttpUtility.UrlEncode(WebBot.TimeStamp()), Channel);

                WebBot.Send(url);
            }
        }

        // When a user joins a channel
        public void UserJoined(object sender, UserEventArgs e)
        {
            if (Enable == "1")
            {
                string flags = "0";
                string url = "";

                // if operator
                if ((e.User.Flags & UserFlags.ChannelOperator) == UserFlags.ChannelOperator)
                {
                    flags = "1";
                }

                if ((string)Bot.GetConfigSetting("showjoinleave") == "1")
                {
                    url = String.Format("{0}u={1}&p={2}&f={3}&d={4}&n={5}&cl={6}&pi={7}&fl={8}&ch={9}&ct={10}&e={11}",
                        WebURL, UserID, Password, 4, HttpUtility.UrlEncode(WebBot.TimeStamp()), HttpUtility.UrlEncode(e.User.Username), e.User.Stats.Product.ProductCode, e.User.Ping, flags, Channel, WebBot.ParseStatstring(e.User.Stats.Product.ProductCode, e.User.Stats.LiteralText, "ClanTag"), "using " + HttpUtility.UrlEncode(e.User.Stats.Product.Name));
                }
                else
                {
                    url = String.Format("{0}u={1}&p={2}&f={3}&d={4}&n={5}&cl={6}&pi={7}&fl={8}&ct={9}",
                        WebURL, UserID, Password, 3, HttpUtility.UrlEncode(WebBot.TimeStamp()), HttpUtility.UrlEncode(e.User.Username), e.User.Stats.Product.ProductCode, e.User.Ping, flags, WebBot.ParseStatstring(e.User.Stats.Product.ProductCode, e.User.Stats.LiteralText, "ClanTag"));
                }

                WebBot.Send(url);
            }
        }

        // When a user leaves the channel
        public void UserLeft(object sender, UserEventArgs e)
        {
            if (Enable == "1")
            {
                string url = "";

                if ((string)Bot.GetConfigSetting("showjoinleave") == "1")
                {
                    url = String.Format("{0}u={1}&p={2}&f={3}&d={4}&n={5}",
                        WebURL, UserID, Password, 16, HttpUtility.UrlEncode(WebBot.TimeStamp()), HttpUtility.UrlEncode(e.User.Username));
                }
                else
                {
                    url = String.Format("{0}u={1}&p={2}&f={3}&d={4}&n={5}",
                        WebURL, UserID, Password, 5, HttpUtility.UrlEncode(WebBot.TimeStamp()), HttpUtility.UrlEncode(e.User.Username));
                }

                WebBot.Send(url);
            }
        }

        // All users currently present in the channel (when the bot first joins)
        public void UserShown(object sender, UserEventArgs e)
        {
            if (Enable == "1")
            {
                // increment amount of users by 1
                UserCount++;

                string flags = "0";
                string url = String.Format("{0}u={1}&p={2}&f={3}", WebURL, UserID, Password, 18);

                // if operator
                if ((e.User.Flags & UserFlags.ChannelOperator) == UserFlags.ChannelOperator)
                {
                    flags = "1";
                }

                // build the string for the URL
                Users += String.Format("&user{0}={1}+{2}+{3}+{4}+{5}",
                    UserCount.ToString(), HttpUtility.UrlEncode(e.User.Username), e.User.Ping, e.User.Stats.Product.ProductCode, flags, WebBot.ParseStatstring(e.User.Stats.Product.ProductCode, e.User.Stats.LiteralText, "ClanTag"));

                // when bot is received, signifies the last user to be in the channel when entered, send request
                if (e.User.Username.ToLower() == (string)Bot.GetConfigSetting("username").ToString().ToLower())
                {
                    WebBot.Send(url + Users);

                    // reset vars for next channel
                    UserCount = 0;
                    Users = "";
                }
            }
        }

        // When a person is op'd, de-op'd, etc
        public void UserFlagsChanged(object sender, UserEventArgs e)
        {
            if (Enable == "1")
            {
                string url = String.Format("{0}u={1}&p={2}&f={3}&n={4}",
                        WebURL, UserID, Password, 12, HttpUtility.UrlEncode(e.User.Username));

                WebBot.Send(url);
            }
        }

        // When someone speaks
        public void UserSpoke(object sender, ChatMessageEventArgs e)
        {
            if (Enable == "1")
            {
                string url = String.Format("{0}u={1}&p={2}&f={3}&d={4}&n={5}&t={6}",
                        WebURL, UserID, Password, 8, HttpUtility.UrlEncode(WebBot.TimeStamp()), HttpUtility.UrlEncode(e.Username), HttpUtility.UrlEncode(e.Text));

                WebBot.Send(url);
            }
        }

        // When someone emotes
        public void UserEmoted(object sender, ChatMessageEventArgs e)
        {
            if (Enable == "1")
            {
                string url = String.Format("{0}u={1}&p={2}&f={3}&d={4}&n={5}&t={6}",
                        WebURL, UserID, Password, 9, HttpUtility.UrlEncode(WebBot.TimeStamp()), HttpUtility.UrlEncode(e.Username), HttpUtility.UrlEncode(e.Text));

                WebBot.Send(url);
            }
        }

        // When the bot talks
        public void MessageSent(object sender, ChatMessageEventArgs e)
        {
            if (Enable == "1")
            {
                string url = String.Format("{0}u={1}&p={2}&f={3}&d={4}&n={5}&t={6}",
                        WebURL, UserID, Password, 19, HttpUtility.UrlEncode(WebBot.TimeStamp()), HttpUtility.UrlEncode(e.Username), HttpUtility.UrlEncode(e.Text));

                WebBot.Send(url);
            }
        }

        // When you receive a whisper
        public void WhisperReceived(object sender, ChatMessageEventArgs e)
        {
            if (Enable == "1")
            {
                if (ShowWhispers)
                {
                    string url = String.Format("{0}u={1}&p={2}&f={3}&d={4}&fr={5}&t={6}",
                        WebURL, UserID, Password, 6, HttpUtility.UrlEncode(WebBot.TimeStamp()), HttpUtility.UrlEncode(e.Username), HttpUtility.UrlEncode(e.Text));

                    WebBot.Send(url);
                }
            }
        }

        // When you send a whisper
        public void WhisperSent(object sender, ChatMessageEventArgs e)
        {
            if (Enable == "1")
            {
                if (ShowWhispers)
                {
                    string url = String.Format("{0}u={1}&p={2}&f={3}&d={4}&to={5}&t={6}",
                        WebURL, UserID, Password, 7, HttpUtility.UrlEncode(WebBot.TimeStamp()), HttpUtility.UrlEncode(e.Username), HttpUtility.UrlEncode(e.Text));

                    WebBot.Send(url);
                }
            }
        }
        #endregion

        #endregion
    }
}
